package croe.jdbc.utils;

import croe.jdbc.domain.SQL;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("unchecked")
public class SqlUtils {

    public static SQL buildInsetSql(Object o) throws Exception {
        SQL sql = ClassMethodUtil.getSQL(o);
        StringBuilder sbSQL = new StringBuilder();
        sbSQL.append("insert into ").append(sql.getTableName()).append(" ");
        StringBuilder columnName = new StringBuilder();
        columnName.append("(");
        StringBuilder valueName = new StringBuilder();
        valueName.append("(");
        for (String cName : sql.getCloumnName()) {
            if (!columnName.toString().equals("(")) {
                columnName.append(",");
            }
            columnName.append(cName);
            if (!valueName.toString().equals("(")) {
                valueName.append(",");
            }
            valueName.append("?");
        }
        columnName.append(")");
        valueName.append(")");
        sbSQL.append(columnName).append(" values ").append(valueName);
        sql.setSql(sbSQL.toString());
        return sql;
    }


    public static String buildDelteSQL(Class<?> clazz) throws Exception {
        SQL sql = ClassMethodUtil.getSQL(clazz);
        StringBuilder deleteSQL = new StringBuilder();
        deleteSQL.append("delete from ").append(sql.getTableName())
                .append(" where ")
                .append(sql.getPrimaryKey()).append("=?");
        return deleteSQL.toString();
    }

    public static String buildDelteBatchSQL(Class<?> clazz, int count) throws Exception {
        SQL sql = ClassMethodUtil.getSQL(clazz);
        StringBuilder deleteSQL = new StringBuilder();
        deleteSQL.append("delete from ").append(sql.getTableName())
                .append(" where ")
                .append(sql.getPrimaryKey()).append(" in (");
        for (int i = 0; i < count; i++) {
            if (i == 0) {
                deleteSQL.append("?");
            } else {
                deleteSQL.append(",?");
            }
        }
        deleteSQL.append(")");
        return deleteSQL.toString();
    }

    public static SQL buildUpdateSQL(Object obj) throws Exception {
        SQL sql = ClassMethodUtil.getUpdateSQL(obj);
        StringBuilder sbSQL = new StringBuilder();
        sbSQL.append("update ").append(sql.getTableName()).append(" set ");
        List<String> cloumnNames = sql.getCloumnName();
        String pkName = sql.getPrimaryKey();
        int i = 0;
        for (String cloumn : cloumnNames) {
            if (!cloumn.equals(pkName)) {
                if (i != 0) {
                    sbSQL.append(",");
                }
                sbSQL.append(cloumn).append(" = ? ");
                i++;
            }
        }
        sql.setSql(sbSQL.append(" where ").append(pkName).append("=?").toString());
        return sql;
    }

    public static String buildQueryByIdSQL(Class<?> clazz) throws Exception {
        SQL sql = ClassMethodUtil.getSQL(clazz);
        StringBuilder querySQL = new StringBuilder();
        querySQL.append("select * ");
        querySQL.append(" from ").append(sql.getTableName()).append(" where ").append(sql.getPrimaryKey()).append(" = ?");
        return querySQL.toString();
    }


    public static String buildQueryByIdsSQL(Class<?> clazz, int count) throws Exception {
        SQL sql = ClassMethodUtil.getSQL(clazz);
        StringBuilder querySQL = new StringBuilder();
        querySQL.append("select * ");
        querySQL.append(" from ").append(sql.getTableName()).append(" where ").append(sql.getPrimaryKey()).append(" in (");
        for (int i = 0; i < count; i++) {
            if (i == 0) {
                querySQL.append("?");
            } else {
                querySQL.append(",?");
            }
        }
        querySQL.append(")");
        return querySQL.toString();
    }


    public static <T> String buildQueryAllSql(Class<T> requiredType) throws Exception {
        SQL sql = ClassMethodUtil.getSQL(requiredType);
        StringBuilder querySQL = new StringBuilder();
        querySQL.append("select * ").append(" from ").append(sql.getTableName());
        return querySQL.toString();
    }


    public static String getCountSQL(String sql) {
        StringBuilder sb = new StringBuilder();
        sb.append("select count(*) from ( ").append(sql).append(" )");
        return sb.toString();
    }

    public static String getPagedListSQL(String sql, int start, int end) {
        StringBuilder sb = new StringBuilder();
        sb.append("select * from (select a.*,rownum rn from  ").append("(")
                .append(sql).append(")a").append(" where rownum <=").append(end)
                .append(")").append("where rn >").append(start);
        return sb.toString();

    }


    public static <T> List<Object[]> getBathParam(List<T> objs) throws Exception {
        if (objs == null || objs.size() == 0)
            return null;
        List<Object[]> bathParam = new ArrayList<Object[]>();
        for (Object obj : objs) {
            SQL sql = ClassMethodUtil.getSQL(obj);
            bathParam.add(sql.getParamsValue().toArray());
        }
        return bathParam;
    }

    public static <T> List<Object[]> getUpdateBathParam(List<T> objs) throws Exception {
        if (objs == null || objs.size() == 0)
            return null;
        List<Object[]> bathParam = new ArrayList<Object[]>();
        for (Object obj : objs) {
            SQL sql = ClassMethodUtil.getSQL(obj);
            List<Object> oldParamsValue = sql.getParamsValue();
            List<Object> newParamsValue = new ArrayList<Object>(oldParamsValue.size());
            for (Object pram : oldParamsValue) {
                if (!sql.getPrimaryKeyValue().equals(pram)) {
                    newParamsValue.add(pram);
                }
            }
            newParamsValue.add(sql.getPrimaryKeyValue());
            bathParam.add(newParamsValue.toArray());
        }
        return bathParam;
    }


    public static <T> List<Object[]> getBathIdsParam(List<T> objs) throws Exception {
        if (objs == null || objs.size() == 0)
            return null;
        List<Object[]> bathIdsParam = new ArrayList<Object[]>();
        for (Object obj : objs) {
            SQL sql = ClassMethodUtil.getSQL(obj);
            Object[] idParam = new Object[]{sql.getPrimaryKeyValue()};
            bathIdsParam.add(idParam);
        }
        return bathIdsParam;
    }


    public static boolean isSql(String sql) {
        //TODO 未实现
        return false;
    }

}
